﻿################################################################################
#region Logger Functions
################################################################################

$script:LogConfig = New-Object PSObject |
	Add-Member -Name "Mode"        -MemberType "NoteProperty" -Value "console" -PassThru |
	Add-Member -Name "ScriptBlock" -MemberType "NoteProperty" -Value $null -PassThru

#-------------------------------------------------------------------------------
function Write-Log
{
	param
	(
		[String[]] $LogString
	)
	switch ($LogConfig.Mode)
	{
		"console" {
			Write-Host $LogString
		}
		"scriptblock" {
			Invoke-Command -ScriptBlock $LogConfig.ScriptBlock -ArgumentList $LogString
		}
		default {
		}
	}
}
#-------------------------------------------------------------------------------

################################################################################
#endregion Logger Functions
################################################################################



################################################################################
#region Other Functions
################################################################################

$utf8  = [System.Text.Encoding]::UTF8
$ascii = [System.Text.Encoding]::ASCII

##------------------------------------------------------------------------------
# Select-FileDialog Function  #
# Created by Hugo Peeters     #
# http://www.peetersonline.nl #
###############################

function Select-FileDialog
{
	param
	(
		[string]$Title,
		[string]$Directory,
		[string]$Filter="All Files (*.*)|*.*"
	)
	[System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms") | Out-Null
	$objForm = New-Object System.Windows.Forms.OpenFileDialog
	$objForm.InitialDirectory = $Directory
	$objForm.Filter = $Filter
	$objForm.Title = $Title
	$Show = $objForm.ShowDialog()
	if ($Show -eq "OK")
	{
		return $objForm.FileName
	}
	else
	{
		return ""
	}
}
##------------------------------------------------------------------------------
function Convert-JsonToXml
{
	param
	(
		[Parameter(ValueFromPipeline=$true)][string[]]$json
	)
	begin
	{
		$mStream = New-Object System.IO.MemoryStream
	}
	process
	{
		$bytes = $utf8.GetBytes($json)
		$mStream.Write($bytes, 0, $bytes.Length)
	}
	end
	{
		$mStream.Position = 0
		$jsonReader = [System.Runtime.Serialization.Json.JsonReaderWriterFactory]::CreateJsonReader($mStream,[System.Xml.XmlDictionaryReaderQuotas]::Max)
		try
		{
			$xml = New-Object Xml.XmlDocument
			$xml.Load($jsonReader)
			$xml
		}
		finally
		{
			$jsonReader.Close()
			$mStream.Dispose()
		}
	}
}
##------------------------------------------------------------------------------

################################################################################
#endregion Other Functions
################################################################################



################################################################################
#region Translate Functions
################################################################################

$WebClient = New-Object System.Net.WebClient
$WebClient.Encoding = $utf8

##------------------------------------------------------------------------------
function New-WordCard
{
	New-Object PSObject -Property @{
		"Text"         = ""
		"Phonetic"     = ""
		"Sound"        = ""
		"PartOfSpeech" = ""
		"Meaning"      = @{}
	}
}
##------------------------------------------------------------------------------
function Update-WordCard
{
	param
	(
		[Parameter(ValueFromPipeline=$true)] $WordCard,
		[String] $Key,
		[String] $Value
	)
	switch ($Key)
	{
		"text" {
			$WordCard.Text = $Value
		}
		"phonetic" {
			$WordCard.Phonetic = $Value
		}
		"sound" {
			$WordCard.Sound = $Value
		}
		"part-of-speech" {
			$WordCard.Meaning.Add($Value, @())
			$WordCard.PartOfSpeech = $Value
		}
		"meaning" {
			#$WordCard.Meaning[$WordCard.PartOfSpeech] += @($Value)
			$WordCard.Meaning[$WordCard.PartOfSpeech] += @{
				"Value"   = $Value
				"Checked" = $true
				}
		}
	}
}
##------------------------------------------------------------------------------
function Get-WordFromDictionary
{
	param
	(
		[Parameter(ValueFromPipeline=$true)]
		[String[]] $WordList
	)
	process
	{
		foreach ($Word in $input)
		{
			Write-Log "Translating '$Word' ..."
			## Prepare word - trim text and replace spaces to '+' sign
			$Word = $Word.Trim() -replace "\s+", "+"
			## Create uri
			$uri = $rcUriPrefix + $Word + $rcUriPostfix
			#Write-Log $uri
			## Get result in JSON format
			Write-Log "Sending request to server ..."
			$json = $WebClient.DownloadString($uri)
			## Cut the JSON string
			$json = $json.Substring(25, $json.Length - 25 - 10) -replace "\\x[0-9a-f]{2}", ""
			## Convert JSON to XML
			$xml = Convert-JsonToXml $json
			$xml.Save("C:\Users\dim\Desktop\asd.xml")

			Write-Log "Processing data ..."
			## Process XML and generate CardList - array of Card
			$CardList = @()
			foreach ($primaries in $xml.root.primaries.'item')
			{
				if ($primaries -eq $null) { continue }
				$Card = New-WordCard
				foreach ($term in $primaries.terms.'item')
				{
					$Card | Update-WordCard -Key $term.SelectSingleNode("type").'#text' -Value $term.SelectSingleNode("text").'#text'
				}
				foreach ($entry in $primaries.entries.'item')
				{
					foreach ($label in $entry.labels.'item')
					{
						if ($label -eq $null) { continue }
						$Card | Update-WordCard -Key $label.SelectSingleNode("title").'#text' -Value $label.SelectSingleNode("text").'#text'
					}
					foreach ($term in $entry.terms.'item')
					{
						if ($term -eq $null) { continue }
						foreach ($label in $term.labels.'item')
						{
							if ($label -eq $null) { continue }
							$Card | Update-WordCard -Key $term.SelectSingleNode("text").'#text' -Value $label.SelectSingleNode("text").'#text'
						}
					}
					foreach ($subentry in $entry.entries.'item')
					{
						if ($subentry -eq $null) { continue }
						foreach ($term in $subentry.terms.'item')
						{
							$Card | Update-WordCard -Key $subentry.SelectSingleNode("type").'#text' -Value $term.SelectSingleNode("text").'#text'
						}
					}
				}
				$Card
			}
			Write-Log "Translating '$Word' ... done"
		}
	}
}
##------------------------------------------------------------------------------

##------------------------------------------------------------------------------
function Get-GLCardKey
{
	param
	(
		[String] $String = "",
		$WordCard = $null,
		[String] $PartOfSpeech = ""
	)
	$GLCardKey = New-Object PSObject -Property @{
		"Text"         = ""
		"PartOfSpeech" = ""
		"Phonetic"     = ""
	} |
	Add-Member -Name "ShortKey" -MemberType ScriptProperty -Value {
		("{0,-15} " -f $this.Text) + $this.Phonetic
	} -PassThru |
	Add-Member -Name "LongKey" -MemberType ScriptProperty -Value {
		("{0,-15} {1,-12} " -f $this.Text, ("/" + $this.PartOfSpeech + "/")) + $this.Phonetic
	} -PassThru
	if ($String -ne "")
	{
		if ($String -match "(.+)\s+\/(.+)\/\s+(\[.+\])")
		{
			$GLCardKey.Text         = $Matches[1].Trim()
			$GLCardKey.PartOfSpeech = $Matches[2].Trim()
			$GLCardKey.Phonetic     = $Matches[3].Trim()
			return $GLCardKey
		}
		
		if ($String -match "(.+)\s+\/(.+)\/")
		{
			$GLCardKey.Text         = $Matches[1].Trim()
			$GLCardKey.PartOfSpeech = $Matches[2].Trim()
			return $GLCardKey
		}
		
		if ($String -match "(.+)\s+(\[.+\])")
		{
			$GLCardKey.Text         = $Matches[1].Trim()
			$GLCardKey.Phonetic     = $Matches[3].Trim()
			return $GLCardKey
		}
	}
	
	if ($WordCard -ne $null)
	{
		if ($PartOfSpeech -eq "")
		{
			$GLCardKey.Text         = $WordCard.Text.Trim()
			$GLCardKey.Phonetic     = $WordCard.Phonetic.Trim()
			return $GLCardKey
		}
		else
		{
			$GLCardKey.Text         = $WordCard.Text.Trim()
			$GLCardKey.PartOfSpeech = $PartOfSpeech.Trim()
			$GLCardKey.Phonetic     = $WordCard.Phonetic.Trim()
			return $GLCardKey
		}
	}
}
##------------------------------------------------------------------------------

##------------------------------------------------------------------------------
function Export-GLCardsToGLFile
{
	param
	(
	)
	$OutputFilePath = $ScriptData.InputFilePath + ".gl"
	Remove-Item -Path $OutputFilePath -Force -ErrorAction SilentlyContinue
	$GLCardList.Values |
		ForEach-Object {
			foreach ($PartOfSpeech in $_.Meaning.Keys)
			{
				$SelectedMeanings = @()
				foreach ($Meaning in $_.Meaning.$PartOfSpeech)
				{
					if ($Meaning.Checked)
					{
						$SelectedMeanings += @($Meaning.Value)
					}
				}
				if ($SelectedMeanings.Count -gt 0)
				{
					$str = $_.Text + " /" + $PartOfSpeech + "/ " + $_.Phonetic
					Write-Host $str
					Add-Content -Path $OutputFilePath -Value $str -Encoding UTF8
					$str = $SelectedMeanings -join ", "
					Write-Host $str
					Add-Content -PassThru $OutputFilePath -Value $str -Encoding UTF8
				}
			}
		}
}
##------------------------------------------------------------------------------

################################################################################
#endregion Translate Functions
################################################################################
